package com.ftg.learn.chapter19.jdbc.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.sql.*;
import java.util.List;
import java.util.function.Supplier;

/**
 * @author KangJx
 * @date 2021/9/6
 */
public class MyJdbc<T> implements JdbcUtil<T> {

    private final String url = "jdbc:mysql://localhost:3306/learnmysql";
    private final String userName = "root";
    private final String password = "Love0913@kjx";

    @Override
    public int insert(T t1) {
        Class c = t1.getClass();

        Field[] fs = c.getDeclaredFields();
        Object[] obj = new Object[fs.length];
        StringBuilder cols = new StringBuilder();
        StringBuilder whys = new StringBuilder();
        int index = 0;
        for(Field f : fs){
            try {
                PropertyDescriptor pd = new PropertyDescriptor(f.getName(),t1.getClass());
                Method rm = pd.getReadMethod();
                cols.append(f.getName()).append(index == fs.length - 1?"":",");
                whys.append("?").append(index == fs.length - 1?"":",");
                obj[index++] = rm.invoke(t1);
            } catch (IntrospectionException| IllegalAccessException |InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        String sql = "insert into "+ c.getSimpleName() +"(" + cols.toString() + ") values (" + whys.toString() + ")" .toUpperCase();
        return doDml(sql,obj);
    }



    @Override
    public int insert(T t1, Object... obj) {
        return 0;
    }

    @Override
    public List<T> queryAll(T t) {
        System.out.println(this.getClass().getGenericSuperclass());
        ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        Type[] ts = type.getActualTypeArguments();
        System.out.println(ts[0].getTypeName());

        return null;
    }

    @Override
    public List<T> queryAllForWhere(T t1, Supplier<String> wh, Object... obj) {
        return null;
    }


    @Override
    public int update(T t1) {
        return 0;
    }

    @Override
    public int delete(T t1) {
        return 0;
    }


    /**
     * 真证完成对数据操作的方法
     * @param sql  执行语句
     * @param obj  参数
     * @return   List<T></T>
     */
//    private List<T> jdbcSelect(String sql,Object...obj){
//        List<T> list = new ArrayList<>();
//        try(
//                Connection conn = DriverManager.getConnection(url,userName,password);
//                PreparedStatement pstmt = conn.prepareStatement(sql);
//        ){
//            if(obj != null){
//                for(int i = 0 ,len = obj.length;i < len;i++){
//                    pstmt.setObject(i + 1 , obj[i]);
//                }
//            }
//            //查询
//            ResultSet rs = pstmt.executeQuery();
//            ResultSetMetaData rsmd = rs.getMetaData();
//            //所有行 创建新的emp
//            while(rs.next()){
//                //o - emp
//                Object o = this.obj.getClass().newInstance();
//                //所有列 要为emp里面的setter赋值
//                for(int i = 0,len =rsmd.getColumnCount(); i < len;i++){
//                    //列名也哪个东西相映射 emp 属性
//                    String colIName = rsmd.getColumnName(i + 1);
//                    //colIname这个属性对应的【getter/setter】
//                    PropertyDescriptor pd = new PropertyDescriptor(colIName,o.getClass());
//                    //setter
//                    Method setter = pd.getWriteMethod();
//                    //取到this.obj.getClass() - colIName字段的类型
//                    String tname = rsmd.getColumnTypeName(i+1);
//                    //newInstance 相当于new
//                    switch (tname){
//                        case "TINYINT":
//                        case "SMALLINT":
//                        case "MEDIUMINT":
//                            setter.invoke(o,rs.getInt(i+1));
//                            break;
//                        case "FLOAT":
//                            setter.invoke(o,rs.getFloat(i+1));
//                            break;
//                        case "DOUBLE":
//                            setter.invoke(o,rs.getDouble(i+1));
//                            break;
//                        case "BIT":
//                        case "BOOLEAN":
//                            setter.invoke(o,rs.getBoolean(i+1));
//                            break;
//                        case "INT":
//                        case "BIGINT":
//                            setter.invoke(o,rs.getLong(i+1));
//                            break;
//                        default:
//                            setter.invoke(o,rs.getObject(i+1));
//                    }
//
//                }
//                //emp emp emp
//                list.add((T)o);
//            }
//
//        }catch (SQLException | IntrospectionException | IllegalAccessException  | InvocationTargetException | InstantiationException e) {
//            e.printStackTrace();
//        }
//        return list;
//    }

    private int doDml(String sql,Object...obj){
        try(
                Connection conn = DriverManager.getConnection(url,userName,password);
                PreparedStatement pstmt = conn.prepareStatement(sql);
        ){
            if(obj != null){
                for(int i = 0 ,len = obj.length;i < len;i++){
                    pstmt.setObject(i + 1 , obj[i]);
                }
            }
            return pstmt.executeUpdate();
        }catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }
}
